home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Alles Voor Internet / Tout Pour Internet
/
alles voor internet.iso
/
MacInternet™
/
Archive-tools
/
untar and compress Folder
/
untar
/
untar.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-12
|
8KB
|
358 lines
#include <stdio.h>
#include <stdlib.h>
#include <console.h>
#include <unix.h>
#include <StandardFile.h>
#include <Files.h>
#include <Dialogs.h>
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned long ulong;
#define NAMESIZE 100
typedef struct
{
char name[NAMESIZE];
char mode[8];
char uid[8];
char gid[8];
char size[12];
char mtime[12];
char checksum[8];
char link[NAMESIZE+2];
char extno[4];
char exttotal[4];
char efsize[12];
} FileInfo;
#define DIGIT(x) ('0' <= (x) && (x) <= '7')
#define VALUE(x) ((x) - '0')
char block[ 512 ];
int listflag = 1;
ulong readnum( char * dp, int maxsize );
void main( int argc, char ** argv );
void HiliteDefault( DialogPtr d );
ulong readnum( char * dp, int maxsize )
{
ulong answer = 0;
while ( ! DIGIT(*dp) && --maxsize > 0 )
dp++;
while ( DIGIT(*dp) && maxsize-- > 0 )
answer = answer * 8 + VALUE(*dp++);
return answer;
}
void main( int argc, char ** argv )
{
int i, j;
long size;
int dflag;
FileInfo * fp;
char * ep;
HParamBlockRec h;
Handle kirk;
extern long _fcreator;
Point p;
SFReply reply;
OSErr err;
FILE * in;
DialogPtr dp;
char tempstr[33];
long templ;
int itemType, itemHit;
Handle item;
Rect itemRect;
int forceFlag = 0;
int convertFlag = 0;
kirk = GetResource( 'KIRK', 128 );
_fcreator = **(long **)kirk;
printf("\n\n" );
printf( "Simple tar extraction utility, version 1.0, by Tim Smith.\n" );
printf( "This program and its source code are in the public domain.\n" );
printf( "\n" );
printf( "Follow the instructions that will be displayed at the bottom\n" );
printf( "of this window for each dialog that is displayed.\n" );
dp = GetNewDialog( 128, 0, (WindowPtr)-1 );
StartOver:
printf( "\n========================================\n" );
printf( "Select a tar archive.\n" );
fflush( stdout );
p.h = 200;
p.v = 50;
SFGetFile( p, 0, 0, -1, 0, 0, &reply );
if ( reply.good == TRUE )
{
PtoCstr( reply.fName );
err = SetVol( 0, reply.vRefNum );
if ( err )
{
printf( "ERROR: could not set directory!\n" );
fflush( stdout );
goto StartOver;
}
in = fopen( (char *)reply.fName, "rb" );
if ( in == NULL )
{
printf( "ERROR: could not open file!\n" );
fflush( stdout );
goto StartOver;
}
}
else
ExitToShell();
fp = (FileInfo *)block;
RedoDialog:
printf( "\n========================================\n" );
printf( "Archive is %s.\n", reply.fName );
printf( "\n" );
printf( "Press LIST to get a listing of the files in the archive. They will be\n" );
printf( "listed with their Unix name (e.g., '/' between components of a path).\n" );
printf( "\n" );
printf( "Press EXTRACT to extract all of the files in the archive. Directories\n" );
printf( "will be created as needed.\n" );
printf( "\n" );
printf( "Press CANCEL to return to the file selection dialog.\n" );
printf( "\n" );
printf( "Set the creator to use for extracted files in the text edit box, and\n" );
printf( "control conversion of text files from Unix to Mac format with the check\n" );
printf( "box. The default creator is in the KIRK 128 resource, by the way.\n" );
fflush( stdout );
GetDItem( dp, 4, &itemType, &item, &itemRect );
tempstr[0] = 4;
tempstr[1] = _fcreator >> 24;
tempstr[2] = _fcreator >> 16;
tempstr[3] = _fcreator >> 8;
tempstr[4] = _fcreator;
SetIText( item, tempstr );
GetDItem( dp, 5, &itemType, &item, &itemRect );
SetCtlValue( item, 1 );
ShowWindow( dp );
SelectWindow( dp );
SelIText( dp, 4, 0, -1 );
do
{
HiliteDefault( dp );
ModalDialog( 0, &itemHit );
if ( itemHit == 5 )
{
GetDItem( dp, 5, &itemType, &item, &itemRect );
SetCtlValue( item, 1 - GetCtlValue(item) );
}
}
while ( itemHit != 1 && itemHit != 2 && itemHit != 3 );
GetDItem( dp, 5, &itemType, &item, &itemRect );
convertFlag = GetCtlValue(item);
HideWindow( dp );
if ( itemHit == 3 )
{
fclose( in );
goto StartOver;
}
GetDItem( dp, 4, &itemType, &item, &itemRect );
GetIText( item, tempstr );
if ( tempstr[0] != 4 )
{
printf( "ERROR: creator set to bogus value! It must be exactly four\n" );
printf( " four characters. Try again." );
fflush( stdout );
goto RedoDialog;
}
_fcreator = tempstr[1];
_fcreator <<= 8;
_fcreator |= tempstr[2] & 0xff;
_fcreator <<= 8;
_fcreator |= tempstr[3] & 0xff;
_fcreator <<= 8;
_fcreator |= tempstr[4] & 0xff;
if ( itemHit == 2 )
listflag = 1;
else
listflag = 0;
printf( "\n\n\n" );
size = 0;
forceFlag = 0;
fseek( in, 0, SEEK_SET );
while ( 1 )
{
if ( fread( block, 512, 1, in ) != 1 )
break;
if ( fp->name[0] == '\0' )
{
break;
}
size = readnum( fp->size, 12 );
for ( i = 0; i < NAMESIZE; i++ )
if ( fp->name[i] == '\0' )
break;
if ( forceFlag == 0 )
{
for ( j = 0; j < i; j++ )
{
if ( fp->name[j] < ' ' || fp->name[j] > 127 )
{
printf( "\nERROR: bad character in file name.\n" );
if ( StopAlert( 129, 0 ) == 2 )
{
forceFlag = 1;
break;
}
else
goto StartOver;
}
}
}
if ( i && fp->name[i-1] == '/' && size == 0 )
{
printf( "DIRECTORY %s\n", fp->name );
if ( ! listflag )
{
int err;
uchar mname[128];
mname[0] = 1;
mname[1] = ':';
if ( fp->name[0] == '/' )
i = 1;
else
i = 0;
for ( ; fp->name[i] != '\0'; i++ )
{
if ( fp->name[i] == '/' )
fp->name[i] = ':';
mname[++mname[0]] = fp->name[i];
}
if ( mname[mname[0]] == ':' && mname[0] > 1 )
mname[0]--;
mname[1+mname[0]] = '\0';
h.fileParam.ioCompletion = 0;
h.fileParam.ioNamePtr = mname;
h.fileParam.ioVRefNum = 0;
h.fileParam.ioDirID = 0;
err = PBDirCreate( &h, 0 );
if ( err )
{
printf( "ERROR: creation of directory failed!\n" );
goto StartOver;
}
}
continue;
}
else if ( fp->link[0] && size == 0 )
{
printf( "WARNING: %s was linked to %s. Ignored\n", fp->name, &fp->link[1] );
continue;
}
else
printf( "%s, %ld bytes\n", fp->name, size );
if ( ! listflag )
{
FILE * wp;
int c;
int pad;
char mname[128];
mname[0] = ':';
if ( fp->name[0] == '/' )
i = 1;
else
i = 0;
for ( c = 1; fp->name[i] != '\0'; i++ )
{
if ( fp->name[i] == '/' )
fp->name[i] = ':';
mname[c++] = fp->name[i];
}
mname[c] ='\0';
pad = (512 - (size % 512)) % 512;
wp = fopen( mname, "wb" );
if ( wp == NULL )
{
printf( "ERROR: could not create!...skipping\n" );
goto skipall;
}
while ( size-- > 0 )
{
c = getc(in);
if ( c == 0x0A && convertFlag )
c = 0x0D;
putc(c,wp);
}
while ( pad-- > 0 )
getc(in);
fclose(wp);
}
else
{
if ( ! listflag )
printf( "---unnamed file skipped\n" );
skipall:
size += 511; size /= 512;
while ( size-- > 0 )
{
if ( fread( block, 512, 1, in ) != 1 )
break;
}
if ( size >= 0 )
{
printf( "ERROR: read failed or unexpected end of file.\n" );
break;
}
}
}
printf( "%s complete.\n", listflag ? "Listing" : "Extraction" );
fflush( stdout );
if ( listflag )
goto RedoDialog;
else
goto StartOver;
}
void HiliteDefault( DialogPtr d )
{
int ItemType;
Handle Item;
Rect ItemRect;
GrafPtr savePort;
GetPort( &savePort );
SetPort( d );
GetDItem( d, 1, &ItemType, &Item, &ItemRect );
InsetRect( &ItemRect, -4, -4 );
PenSize( 3, 3 );
FrameRoundRect( &ItemRect, 16, 16 );
SetPort( savePort );
}